﻿using System;
using System.Runtime.InteropServices;
using System.Text;

namespace HYRElectric.PowerSystem
{
	public class KeyboardHook
	{
		[DllImport("user32.dll")]
		private static extern int SetWindowsHookEx(int idHook, KeyboardHook.HookProc lpfn, IntPtr hInstance, int threadId);

		[DllImport("user32.dll")]
		private static extern bool UnhookWindowsHookEx(int idHook);

		[DllImport("user32.dll")]
		private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

		[DllImport("kernel32.dll")]
		public static extern IntPtr GetModuleHandle(string lpModuleName);

		[DllImport("kernel32.dll")]
		public static extern int GetCurrentThreadId();

		public KeyboardHook(IntPtr hWnd, IntPtr hWndRevit)
		{
			this.m_HWnd = hWnd;
			this.m_HWndRevit = hWndRevit;
		}

		public void HookStart()
		{
			if (KeyboardHook.hKeyboardHook == 0)
			{
				this.KeyboardHookProcedure = new KeyboardHook.HookProc(this.KeyboardHookProc);
				IntPtr zero = IntPtr.Zero;
				int threadId = 0;
				KeyboardHook.hKeyboardHook = KeyboardHook.SetWindowsHookEx(13, this.KeyboardHookProcedure, zero, threadId);
				if (KeyboardHook.hKeyboardHook == 0)
				{
					this.HookStop();
					throw new Exception("SetWindowsHookEx failed.");
				}
			}
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		[DllImport("user32.dll")]
		private static extern IntPtr GetForegroundWindow();

		[DllImport("user32.dll")]
		private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

		private IntPtr GetActiveWindowIntPtr()
		{
			new StringBuilder(256);
			return KeyboardHook.GetForegroundWindow();
		}

		private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam)
		{
			if (nCode >= 0 && ((KeyboardHook.KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHook.KeyBoardHookStruct))).vkCode == 27)
			{
				IntPtr activeWindowIntPtr = this.GetActiveWindowIntPtr();
				if (activeWindowIntPtr == this.m_HWnd || activeWindowIntPtr == this.m_HWndRevit)
				{
					int wMsg = 16;
					KeyboardHook.SendMessage(this.m_HWnd, wMsg, IntPtr.Zero, IntPtr.Zero);
				}
			}
			return KeyboardHook.CallNextHookEx(KeyboardHook.hKeyboardHook, nCode, wParam, lParam);
		}

		public void HookStop()
		{
			bool flag = true;
			if (KeyboardHook.hKeyboardHook != 0)
			{
				flag = KeyboardHook.UnhookWindowsHookEx(KeyboardHook.hKeyboardHook);
				KeyboardHook.hKeyboardHook = 0;
			}
			if (!flag)
			{
				throw new Exception("UnhookWindowsHookEx failed.");
			}
		}

		private static int hKeyboardHook;

		private KeyboardHook.HookProc KeyboardHookProcedure;

		private IntPtr m_HWnd;

		private IntPtr m_HWndRevit;

		[StructLayout(LayoutKind.Sequential)]
		public class KeyBoardHookStruct
		{
			public int vkCode;

			public int scanCode;

			public int flags;

			public int time;

			public int dwExtraInfo;
		}

		private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
	}
}
